package com.sheepone.util;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.List;

/**
 * @author Miss.杨
 * @description
 * @since 2024/2/21 - 9:56
 */
public class ReflectUtil {
    public static Field[] accessibleDeclaredFields(Class<?> clazz){
        if(!ObjectUtil.isSingleType(clazz)){
            throw new IllegalArgumentException("clazz must be single type");
        }
        Field[] fields = clazz.getDeclaredFields();
        accessible(true,fields);
        return fields;
    }
    public static void accessible(AccessibleObject... accessibleObjects){
        accessible(true,accessibleObjects);
    }

    public static void accessible(boolean accessible,AccessibleObject... accessibleObjects){
        for (AccessibleObject accessibleObject : accessibleObjects) {
            accessibleObject.setAccessible(accessible);
        }
    }
    public static <T> T writeStringToBasicObject(String value, Class<T> clazz) throws ClassNotFoundException {
        if(clazz==String.class){
            return (T) value;
        }else if(clazz==Integer.class || clazz==int.class){
            return (T) Integer.valueOf(value);
        }else if(clazz==Long.class || clazz==long.class){
            return (T) Long.valueOf(value);
        }else if (clazz==Double.class || clazz==double.class){
            return (T) Double.valueOf(value);
        }else if(clazz==Float.class || clazz==float.class){
            return (T) Float.valueOf(value);
        }else if(clazz==Boolean.class || clazz==boolean.class){
            return (T) Boolean.valueOf(value);
        }else if(clazz==Byte.class || clazz==byte.class){
            return (T) Byte.valueOf(value);
        }else if (clazz==Short.class || clazz==short.class){
            return (T) Short.valueOf(value);
        }else if(clazz==Character.class || clazz==char.class){
            return (T) Character.valueOf(value.charAt(0));
        }
        throw new ClassNotFoundException("field type is not support");
    }
    public static <T> void writeStringToBasicField(Field field, T instance, String value, Class<?> fieldType) throws IllegalAccessException, ClassNotFoundException {
        if (fieldType==int.class||fieldType==Integer.class) {
            if (fieldType == int.class) {
                field.set(instance, Integer.parseInt(value));
            } else {
                field.set(instance, Integer.valueOf(value));
            }
        }
        else if (fieldType==String.class) {
            field.set(instance, value);
        }
        else if (fieldType==long.class||fieldType==Long.class) {
            if (fieldType==long.class) {
                field.set(instance, Long.parseLong(value));
            }else{
                field.set(instance, Long.valueOf(value));
            }
        }
        else if (fieldType==double.class||fieldType==Double.class) {
            if (fieldType==double.class) {
                field.set(instance, Double.parseDouble(value));
            }else{
                field.set(instance, Double.valueOf(value));
            }
        }
        else if (fieldType==float.class||fieldType==Float.class) {
            if (fieldType==float.class) {
                field.set(instance, Float.parseFloat(value));
            }else{
                field.set(instance, Float.valueOf(value));
            }
        }
        else if (fieldType==boolean.class||fieldType==Boolean.class) {
            if (fieldType==boolean.class) {
                field.set(instance, Boolean.parseBoolean(value));
            }else{
                field.set(instance, Boolean.valueOf(value));
            }
        }
        else if (fieldType==char.class||fieldType==Character.class) {
            if (fieldType==char.class) {
                field.set(instance,value.charAt(0));
            }else{
                field.set(instance, value.charAt(0));
            }
        }
        else if (fieldType==byte.class||fieldType==Byte.class) {
            if (fieldType==byte.class) {
                field.set(instance, Byte.parseByte(value));
            }else{
                field.set(instance, Byte.valueOf(value));
            }
        }
        else if (fieldType==short.class||fieldType==Short.class) {
            if (fieldType==short.class) {
                field.set(instance, Short.parseShort(value));
            }else{
                field.set(instance, Short.valueOf(value));
            }
        }else {
            throw new ClassNotFoundException("field type is not support");
        }

    }

    public static <T> void writeStringsToBasicArray(Field field, T instance,
                                                     List<String> valueStrs, Class<?> componentType) throws IllegalAccessException, ClassNotFoundException {
        if(componentType==int.class||componentType==Integer.class){
            if (componentType==int.class) {
                int[] ints = new int[valueStrs.size()];
                for (int i = 0; i < ints.length; i++) {
                    ints[i]=Integer.parseInt(valueStrs.get(i));
                }
                field.set(instance, ints);
            }else{
                Integer[] ints = new Integer[valueStrs.size()];
                for (int i = 0; i < ints.length; i++) {
                    ints[i]=Integer.valueOf(valueStrs.get(i));
                }
                field.set(instance, ints);
            }
        }
        else if(componentType==String.class){
            String[] strings = new String[valueStrs.size()];
            for (int i = 0; i < strings.length; i++) {
                strings[i]=valueStrs.get(i);
            }
            field.set(instance, strings);
        }
        else if(componentType==long.class||componentType==Long.class){
            if (componentType==long.class){
                long[] longs = new long[valueStrs.size()];
                for (int i = 0; i < longs.length; i++) {
                    longs[i]=Long.parseLong(valueStrs.get(i));
                }
                field.set(instance, longs);
            }else{
                Long[] longs = new Long[valueStrs.size()];
                for (int i = 0; i < longs.length; i++) {
                    longs[i]=Long.valueOf(valueStrs.get(i));
                }
                field.set(instance, longs);
            }
        }
        else if(componentType==double.class||componentType==Double.class){
            if (componentType==double.class){
                double[] doubles = new double[valueStrs.size()];
                for (int i = 0; i < doubles.length; i++) {
                    doubles[i]=Double.parseDouble(valueStrs.get(i));
                }
                field.set(instance, doubles);
            }else{
                Double[] doubles = new Double[valueStrs.size()];
                for (int i = 0; i < doubles.length; i++) {
                    doubles[i]=Double.valueOf(valueStrs.get(i));
                }
                field.set(instance, doubles);
            }
        }
        else if(componentType==float.class||componentType==Float.class){
            if (componentType==float.class){
                float[] floats = new float[valueStrs.size()];
                for (int i = 0; i < floats.length; i++) {
                    floats[i]=Float.parseFloat(valueStrs.get(i));
                }
                field.set(instance, floats);
            }else{
                Float[] floats = new Float[valueStrs.size()];
                for (int i = 0; i < floats.length; i++) {
                    floats[i]=Float.valueOf(valueStrs.get(i));
                }
                field.set(instance, floats);
            }
        }
        else if(componentType==boolean.class||componentType==Boolean.class){
            if (componentType==boolean.class){
                boolean[] bools = new boolean[valueStrs.size()];
                for (int i = 0; i < bools.length; i++) {
                    bools[i]=Boolean.parseBoolean(valueStrs.get(i));
                }
                field.set(instance, bools);
            }else{
                Boolean[] bools = new Boolean[valueStrs.size()];
                for (int i = 0; i < bools.length; i++) {
                    bools[i]=Boolean.valueOf(valueStrs.get(i));
                }
                field.set(instance, bools);
            }
        }
        else if(componentType==char.class||componentType==Character.class){
            if (componentType==char.class){
                char[] chars = new char[valueStrs.size()];
                for (int i = 0; i < chars.length; i++) {
                    chars[i]=valueStrs.get(i).charAt(0);
                }
                field.set(instance, chars);
            }else{
                Character[] chars = new Character[valueStrs.size()];
                for (int i = 0; i < chars.length; i++) {
                    chars[i]= valueStrs.get(i).charAt(0);
                }
                field.set(instance, chars);
            }
        }
        else if(componentType==byte.class||componentType==Byte.class){
            if (componentType==byte.class){
                byte[] bytes = new byte[valueStrs.size()];
                for (int i = 0; i < bytes.length; i++) {
                    bytes[i]=Byte.parseByte(valueStrs.get(i));
                }
                field.set(instance, bytes);
            }else{
                Byte[] bytes = new Byte[valueStrs.size()];
                for (int i = 0; i < bytes.length; i++) {
                    bytes[i]=Byte.valueOf(valueStrs.get(i));
                }
                field.set(instance, bytes);
            }
        }
        else if(componentType==short.class||componentType==Short.class){
            if (componentType==short.class){
                short[] shorts = new short[valueStrs.size()];
                for (int i = 0; i < shorts.length; i++) {
                    shorts[i]=Short.parseShort(valueStrs.get(i));
                }
                field.set(instance, shorts);
            }else{
                Short[] shorts = new Short[valueStrs.size()];
                for (int i = 0; i < shorts.length; i++) {
                    shorts[i]=Short.valueOf(valueStrs.get(i));
                }
                field.set(instance, shorts);
            }
        }else {
            throw new ClassNotFoundException("field type is not support");
        }

    }

    public static <T> void setValue(Field field, T object, Object value) {
        try {
            field.set(object, value);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
    public static Object getValue(Field field, Object object) {
        try {
            return field.get(object);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
